# 作者： 李泉志
# 2025年01月08日17时57分秒
# 2947029073@qq.com

"""
04. 初始化方法
4.1 之前代码存在的问题 —— 在类的外部给对象增加属性
• 在日常开发中，不推荐在类的外部给对象增加属性
    – 如果在运行时，没有找到属性，程序会报错
    AttributeError: 'Dog' object has no attribute 'cute'
• 对象应该包含有哪些属性，应该封装在类的内部！

4.2 初始化方法
• 当使用 类名() 创建对象时，会自动执行以下操作：
a) 为对象在内存中分配空间 —— 创建对象
b) 为对象的属性设置初始值 —— 初始化方法(init)
• 这个初始化方法就是 __init__ 方法，__init__ 是对象的内置方法
__init__ 方法是专门用来定义一个类具有哪些属性的方法！
在 Cat 中增加 __init__ 方法，验证该方法在创建对象时会被自动调用

4.3 在初始化方法内部定义属性
• 在 __init__ 方法内部使用 self.属性名 = 属性的初始值就可以定义属性
• 定义属性之后，再使用Cat类创建的对象，都会拥有该属性

4.4 改造初始化方法 —— 初始化的同时设置初始值
• 在开发中，如果希望在 创建对象的同时，就设置对象的属性，可以对
__init__ 方法进行 改造
1) 把希望设置的属性值，定义成 __init__ 方法的参数
2) 在方法内部使用 self.属性 = 形参 接收外部传递的参数
3) 在创建对象时，使用类名(属性 1, 属性 2...) 调用
"""
"""
05. 内置方法和属性
__del__  对象被从内存中销毁前，会被自动调用
__str__  返回对象的描述信息，print函数输出使用

5.1 __del__ 方法（知道）
• 在 Python 中
    – 当使用 类名() 创建对象时，为对象分配完空间后，自动调用__init__方法
    – 当一个对象被从内存中销毁前，会自动调用__del__方法
• 应用场景
    – __init__ 改造初始化方法，可以让创建对象更加灵活
    – __del__ 如果希望在对象被销毁前，再做一些事情，可以考虑一下
• 生命周期
    – 一个对象从调用 类名() 创建，生命周期开始
    – 一个对象的__del__方法一旦被调用，生命周期结束
    – 在对象的生命周期内，可以访问对象属性，或者让对象调用方法
    
5.2 __str__ 方法
• 在 Python中，使用 print 输出 对象变量，默认情况下，会输出这个变量 引用
的对象是由哪一个类创建的对象，以及在内存中的地址（十六进制表示）
• 如果在开发中，希望使用print输出 对象变量 时，能够打印自定义的内容，
    就可以利用 __str__ 这个内置方法了
注意：__str__ 方法必须返回一个字符串!
"""


class Cat:
    def __init__(self, new_name):
        print("这是一个初始化方法")
        # self.属性名 = 属性的初始值
        # self.name = "Tom"
        self.name = new_name

    def eat(self):
        print("%s爱吃鱼" % self.name)

    def __del__(self):
        print(f"{self.name}对象被销毁了")

    def __str__(self):
        return f"{self.name}"  # 返回值必须是字符串



def main():
    little_cat = Cat("小猫")
    print(little_cat)  # 若有__str__方法，则打印__str__返回值
    # 默认打印对象地址：<__main__.Cat object at 0x0000026AF818D940>

if __name__ == '__main__':
    lazy_cat = Cat("大懒猫")
    lazy_cat.eat()
    tom = Cat("Tom")
    del tom
    main()  # main()结束，小猫作为局部变量被回收
    print("end")
    # end之后也就是整个程序结束，未释放的大懒猫也释放了
